package com.yuandian.management.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.management.entity.ConfBusiness;
import com.yuandian.api.management.entity.ConfExclusiveIndicator;
import com.yuandian.api.management.validate.InsertFlag;
import com.yuandian.api.management.validate.UpdateFlag;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.log.annotation.SysLog;
import com.yuandian.constant.Constants;
import com.yuandian.enums.ResultCodeEnum;
import com.yuandian.management.service.ConfBusinessService;
import com.yuandian.management.service.ConfExclusiveIndicatorService;
import com.yuandian.management.vo.SearchOptionVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import javax.validation.groups.Default;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 *	业务配置模块
 */
@Slf4j
@Api(tags = "业务监控配置-业务配置")
@RestController
@RequestMapping("/business")
public class ConfBusinessController {

	@Autowired
	private ConfBusinessService confBusinessService;

	@Autowired
	private ConfExclusiveIndicatorService confExclusiveIndicatorService;

	/**
	 * 通过主键查询数据
	 *
	 * @param idList 主键集合
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "通过主键查询数据", notes = "通过主键查询数据，支持批量查询")
	@GetMapping("/{ids}")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "id(支持多选)", paramType = "path", required = true, dataType = "Integer")
	})
	public R<List<ConfBusiness>> queryByIds(@PathVariable("ids") List<Integer> idList) {
		return R.ok(confBusinessService.listByIds(idList));
	}

	/**
	 * 通过业务编码查询数据
	 *
	 * @param businessCode 业务编码
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "通过业务编码查询数据", notes = "通过业务编码查询数据")
	@GetMapping("getBusiness/{businessCode}")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "businessCode", value = "业务编码", paramType = "path", required = true, dataType = "String")
	})
	public R<ConfBusiness> queryByBusinessCode(@PathVariable("businessCode") String businessCode) {
		QueryWrapper<ConfBusiness> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("business_code", businessCode);
		return R.ok(confBusinessService.getOne(queryWrapper));
	}

	/**
	 * 分页查询
	 *
	 * @param confBusiness 筛选条件
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "分页查询", notes = "分页查询")
	@PostMapping
	@ApiImplicitParams({
			@ApiImplicitParam(name = "systemId", value = "所属系统id", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "name", value = "业务名称", paramType = "body", required = false, dataType = "String"),
			@ApiImplicitParam(name = "isKey", value = "是否为关键业务，0：否(默认)、1：是", paramType = "body", required = false, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "isConfirm", value = "是否确认", paramType = "body", required = false, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "type", value = "步骤类型，1：首步骤、2：中间步骤、3：末步骤", paramType = "body", required = false, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "pageSize", value = "每页大小", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "pageNum", value = "当前页数", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "isAsc", value = "排序的方向值只能是 desc 或者 asc", paramType = "body", required = true, dataType = "String")
	})
	public R<Page<ConfBusiness>> listPage(@RequestBody @ApiIgnore ConfBusiness confBusiness) {
		return R.ok(confBusinessService.listPage(confBusiness));
	}

	/**
	 * 新增数据
	 *
	 * @param confBusiness 实例对象
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "新增数据", notes = "新增数据")
	@SysLog("新增业务配置表数据")
	@PostMapping("/save")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "systemId", value = "所属系统id", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "name", value = "业务名称", paramType = "body", required = true, dataType = "String"),
			@ApiImplicitParam(name = "isKey", value = "是否为关键业务，0：否(默认)、1：是", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "sequence", value = "显示顺序", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "type", value = "步骤类型，1：首步骤、2：中间步骤、3：末步骤", paramType = "body", required = true, dataTypeClass = Integer.class),
	})
	public R<String> save(@Validated({InsertFlag.class})  @RequestBody @ApiIgnore ConfBusiness confBusiness) {
		return confBusinessService.saveBusiness(confBusiness);
	}

	/**
	 * 通过主键更新数据
	 *
	 * @param confBusiness 实例对象
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "通过主键更新数据", notes = "通过主键更新数据")
	@SysLog("更新业务配置表数据")
	@PutMapping
	@ApiImplicitParams({
			@ApiImplicitParam(name = "systemId", value = "所属系统id", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "name", value = "业务名称", paramType = "body", required = true, dataType = "String"),
			@ApiImplicitParam(name = "isKey", value = "是否为关键业务，0：否(默认)、1：是", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "sequence", value = "显示顺序", paramType = "body", required = true, dataTypeClass = Integer.class),
			@ApiImplicitParam(name = "type", value = "步骤类型，1：首步骤、2：中间步骤、3：末步骤", paramType = "body", required = true, dataTypeClass = Integer.class)
	})
	public R<String> updateById(@Validated({UpdateFlag.class, Default.class}) @ApiIgnore @RequestBody ConfBusiness confBusiness) {
		return confBusinessService.updateBusinessById(confBusiness);
	}

	/**
	 * 通过主键删除数据
	 *
	 * @param businessIds 主键
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "通过主键删除数据", notes = "通过主键删除数据")
	@DeleteMapping("/delete/{businessIds}")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "businessIds", value = "业务id(支持多选)", paramType = "path", required = true, dataTypeClass = Integer.class)
	})
	public R<Boolean> removeByIds(@PathVariable("businessIds") List<Integer> businessIds) {
		return R.ok(confBusinessService.removeBatchByIds(businessIds));
	}


	/**
	 * 通过主键确认业务
	 *
	 * @param ids 主键
	 * @return 通用返回对象
	 */
	@ApiOperation(value = "通过主键确认业务", notes = "通过主键确认业务")
	@GetMapping("confirm/{ids}")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "业务id(支持多选)", paramType = "path", required = true, dataTypeClass = Integer.class)
	})
	public R<Boolean> confirm(@PathVariable List<Integer> ids) {
		if(confBusinessService.confirmBusiness(ids, true)){
			return R.ok();
		}
		return R.failed(ResultCodeEnum.BUSINESS_CONFIRM_FAIL.getMsg());
	}


	/**
	 * 下载专属指标导入模板
	 * @param response 响应上下文
	 */
	@ApiOperation(value = "下载专属指标导入模板", notes = "下载专属指标导入模板")
	@GetMapping("/importTemplate")
	public void importTemplate(HttpServletResponse response) throws IOException {
		try {
			confExclusiveIndicatorService.importTemplate(response);
		} catch (Exception e1) {
			log.error("专属指标导入失败：{}", e1);
			response.getWriter().println(JSONUtil.parse(
					R.failed("该服务资源不存在，请重新刷新页面！")));
		}
	}


	/**
	 * 批量多资源导入专属指标
	 * @param file excel文件
	 * @return 通用返回对象
	 */
	@PostMapping("/batchImport")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "resourceCodes", value = "步骤编码", paramType = "query", required = true, dataTypeClass = Integer.class)
	})
	public R batchImportExcel(@RequestParam(value = "file") MultipartFile file,
								   @RequestParam(value = "resourceCodes") String resourceCodes) {
		if (ObjectUtil.isEmpty(resourceCodes)) {
			return R.failed("服务资源编码不能为空");
		}
		try {
			List<String> list = Arrays.asList(resourceCodes.split(","));
			return confExclusiveIndicatorService.importExcel(file, list);
		} catch (Exception e) {
			log.error("专属指标导入失败：{}", e);
		}
		return R.failed("导入失败");
	}


	/**
	 * 通过主键取消业务
	 * @param ids 主键
	 * @return Boolean
	 */
	@ApiOperation(value = "通过主键取消业务", notes = "通过主键取消业务")
	@GetMapping("/cancel/{ids}")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ids", value = "业务id(支持多选)", paramType = "query", required = true, dataTypeClass = Integer.class)
	})
	public R<Boolean> cancel(@PathVariable List<Integer> ids) {
		if(confBusinessService.confirmBusiness(ids, false)){
			return R.ok();
		}
		return R.failed("该业务已刷新,请忽重复刷新");
	}

	/**
	 * 导出(下载)专属指标列表
	 * @param exclusiveIndicator 专属指标查询参数
	 */
	@PostMapping("/download")
	@ApiOperation(value = "导出(下载)专属指标列表", notes = "导出(下载)专属指标列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "resourceCodes", value = "资源编码(支持多选)", paramType = "body", required = true, dataType = "String"),
	})
	public void download(@RequestBody @ApiIgnore ConfExclusiveIndicator exclusiveIndicator, HttpServletResponse response) {
		try {
			confExclusiveIndicatorService.downloadExclusiveIndicators(exclusiveIndicator, response);
		} catch (Exception e1) {
			log.error(e1.getMessage(), e1);
			response.reset();
			response.setContentType(Constants.CONTENT_TYPE_APPLICATION_JSON);
			response.setCharacterEncoding("utf-8");
			try {
				response.getWriter().println(JSONUtil.parse(R.failed("导出Excel文件失败！")));
			} catch (IOException e2) {
				log.error("专属指标导出失败：{}", e2);
			}
		}
	}


	/**
	 * 通过系统id获取改系统下的业务数(远程接口）
	 * @param systemIds 主键
	 * @return 通用返回对象
	 */
	@ApiIgnore
	@GetMapping("/getBusinessCountBySystemIds/{systemIds}")
	public R<List<Map<String, Integer>>> getBusinessCountBySystemIds(@PathVariable("systemIds") List<Integer> systemIds) {
		return R.ok(confBusinessService.getBusinessCountBySystemIds(systemIds));
	}


	/**
	 * 专属指标导入导出功能查询业务(远程接口）
	 * @param confBusiness 业务vo
	 * @return 通用返回对象
	 */
	@PostMapping("/queryToImport")
	@ApiIgnore
	public R<Page<ConfBusiness>> queryToImport(@RequestBody ConfBusiness confBusiness) {
		return R.ok(confBusinessService.queryToImport(confBusiness));
	}

	/**
	 * 通过系统id查询已确认的关键业务列表(远程接口）
	 * @param systemId 业务vo
	 * @return 通用返回对象
	 */
	@GetMapping(value = {"/queryKeyBusinessBySystemId/{systemId}", "/queryKeyBusinessBySystemId"})
	@ApiIgnore
	public R<List<ConfBusiness>> queryKeyBusinessBySystemId(@PathVariable(value = "systemId", required = false) Integer systemId) {
		return R.ok(confBusinessService.queryKeyBusinessBySystemId(systemId));
	}

	/**
	 * 根据各种过滤条件查询business 数据
	 * @param confBusiness 业务vo
	 * @return 通用返回对象
	 */
	@PostMapping("/getBusiness")
	@ApiIgnore
	public R<List<ConfBusiness>> getBusiness(@RequestBody ConfBusiness confBusiness) {
		return R.ok(confBusinessService.list(Wrappers.query(confBusiness)));
	}


	/**
	 * 根据步骤编码查询所诉业务
	 * @return 通用返回对象
	 */
	@PostMapping("/queryBusinessCodeListByStepCode")
	@ApiIgnore
	public R<List<String>> queryBusinessCodeListByStepCode(@RequestBody List<String> stepCodes) {
		return R.ok(confBusinessService.queryBusinessCodeListByStepCode(stepCodes));
	}

	/**
	 * 根据步骤编码查询所诉业务
	 * @return 通用返回对象
	 */
	@GetMapping("/queryBusinessBySystemId/{systemId}")
	public R<List<SearchOptionVo>> queryBusinessBySystemId(@PathVariable(value = "systemId") Integer systemId) {
		List<SearchOptionVo> searchOptionVos = confBusinessService.queryBusinessBySystemId(systemId);
		return R.ok(searchOptionVos);
	}


}
